#include "hal_serial_console.h"

#define CONSOLE_STK_SIZE      128
#define CONSOLE_TASK_PRIO     (configMAX_PRIORITIES)
TaskHandle_t                hal_console_Task_Handler;

ConsoleDev_S console_dev =
{
    .API_Match_flag = OFF,
    .debug_flag = OFF,
    .func_list = usmart_nametab,
    .func_num = hce_adapter_num,
};

static int hal_serial_string_sep(char *cmd)
{
    char *token = NULL;
    char *param = NULL;
    char buf[LOG_SERVICE_BUFLEN];
    char *copy = buf;
    uint8_t cmd_list_len = 0;
    struct _hal_serial_str_cmp *cmd_str;

    if(*cmd == NULL)
        return -1;
    cmd_str = console_dev.func_list;
    cmd_list_len = console_dev.func_num();
    strncpy(copy, cmd, LOG_SERVICE_BUFLEN - 1);
    token = strtok(copy, " ");
    param = strtok(NULL, "\0");
    if(strcmp(token,"help") == 0)
    {
        DBG_MSG("=================================\r\n");
        DBG_MSG("function list:\r\n");
        for (size_t i = 0; i < cmd_list_len; i++)
        {
            DBG_MSG("%d:%s\r\n",i,cmd_str->name);
            cmd_str++;
        }
        DBG_MSG("=================================\r\n");
        return -2;
    }
    for (int i = 0; i < cmd_list_len; i++)
    {
        if(strcmp(token,cmd_str->name) == 0)
        {
			DBG_MSG("CMD:%s %s\r\n",token,param);
            cmd_str->func(param);
            console_dev.API_Match_flag = ON;
            break;
        }
        cmd_str++;
    }
    if(console_dev.API_Match_flag == OFF)
    {
        DBG_MSG("=================================\r\n");
        DBG_MSG("Unknown cmd:%s\r\n",token);
        DBG_MSG("KEY \"help\" for more infomation?\r\n");
        DBG_MSG("=================================\r\n");
    }
    else
    {
        console_dev.API_Match_flag = OFF;
    }
    return SUCCESS;
}

uint8_t hal_console_parse_param(char *buf, char **argv)
{
    int argc = 1;
    char str_buf[LOG_SERVICE_BUFLEN];
    memset(str_buf, 0, LOG_SERVICE_BUFLEN);
    int str_count = 0;
    int buf_cnt = 0;
    static char temp_buf[LOG_SERVICE_BUFLEN];
    char *buf_pos = temp_buf;
    memset(temp_buf, 0, sizeof(temp_buf));
    if (buf == NULL) 
    {
        goto exit;
    }
    strncpy(temp_buf, buf, LOG_SERVICE_BUFLEN - 1);
    while ((argc < MAX_ARGC) && (*buf_pos != '\0'))
    {
        while ((*buf_pos == ' ') || (*buf_pos == '[') || (*buf_pos == ']'))
        {
            if ((*buf_pos == ' ') && (*(buf_pos + 1) == ' '))
            {
                argv[argc] = NULL;
                argc++;
            }
            *buf_pos = '\0';
            buf_pos++;
        }
        if (*buf_pos == '\0') 
        {
            break;
        }
        else if (*buf_pos == '"') 
        {
            memset(str_buf, '\0', LOG_SERVICE_BUFLEN);
            str_count = 0;
            buf_cnt = 0;
            *buf_pos = '\0';
            buf_pos ++;
            if (*buf_pos == '\0') 
            {
                break;
            }
            argv[argc] = buf_pos;
            while ((*buf_pos != '"') && (*buf_pos != '\0'))
            {
                if (*buf_pos == '\\')
                {
                    buf_pos ++;
                    buf_cnt++;
                }
                str_buf[str_count] = *buf_pos;
                str_count++;
                buf_cnt++;
                buf_pos ++;
            }
            *buf_pos = '\0';
            memcpy(buf_pos - buf_cnt, str_buf, buf_cnt);
        }
        else
        {
            argv[argc] = buf_pos;
        }
        argc++;
        buf_pos++;
        while ((*buf_pos != ' ') && (*buf_pos != '\0') && (*buf_pos != '[') && (*buf_pos != ']'))
        {
            buf_pos++;
        }
    }
    if(console_dev.debug_flag == ON)
    {
        for(uint8_t i=0;i<argc;i++)
        {
            DBG_MSG("argv[%d]:%s\r\n",i,argv[i]);
        }
    }
    exit:
        return argc;
}


static void hal_serial_console_task(void *pvParameters)
{
    pvParameters = pvParameters;
    while (1)
    {
        if(sys_usmart_getstring(console_dev.USMART_RX_BUF) > 0)
        {
            hal_serial_string_sep(console_dev.USMART_RX_BUF);
            memset(console_dev.USMART_RX_BUF,0,RX_BUFF_LEN);
        }
        vTaskDelay(50);
    }
}

void hal_serial_console_task_init(void)
{
    BaseType_t ret = RET_SUCCESS;
    ret = xTaskCreate((TaskFunction_t) hal_serial_console_task,
            (const char*)   "console",
            (uint16_t)      CONSOLE_STK_SIZE,
            (void*)         NULL,
            (UBaseType_t)   CONSOLE_TASK_PRIO,
            (TaskHandle_t*) &hal_console_Task_Handler);
    if(ret < 0)
    {
        DBG_ERR("console task create fail\r\n");
    }
}
